package group.hhsw.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import group.hhsw.common.model.User;
import group.hhsw.common.model.params.LoginParam;
import group.hhsw.common.model.params.RegisterParam;
import group.hhsw.common.model.params.SetUserParam;
import group.hhsw.common.model.vo.UserVo;
import group.hhsw.user.utils.ErrorCode;
import group.hhsw.common.utils.Result;
import group.hhsw.user.mapper.UserMapper;
import group.hhsw.user.service.UserService;
import group.hhsw.user.utils.JwtUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private final static String SALT = "h123...";

    /**
     * 获取用户所在地域
     *
     * @param id 用户id
     * @return 用户所在地域
     */
    @Override
    public String getUserArea(Long id) {
        User user = userMapper.selectById(id);
        return user.getArea();
    }

    /**
     * 获取用户的标签
     *
     * @param id 用户id
     * @return 用户的标签
     */
    @Override
    public String getUserLabel(Long id) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .select(User::getLabel)
                .eq(User::getId, id));
        return user.getLabel();
    }

    @Override
    public List<UserVo> getAllUsers() {
        List<User> users = userMapper.selectList(new QueryWrapper<User>());
        ArrayList<UserVo> userVos = new ArrayList<>();
        for (User u : users) {
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(u, userVo);
            userVos.add(userVo);
        }
        return userVos;
    }

    /**
     * 登录
     *
     * @param loginParam 登录参数
     * @return token
     */
    @Override
    public Result login(LoginParam loginParam) {
        String account = loginParam.getAccount();
        String password = loginParam.getPassword();
        if (account == null || password == null) {
            return Result.fail(ErrorCode.PARAM_ERROR.getCode(), ErrorCode.PARAM_ERROR.getMsg());
        }
        String s = DigestUtils.md5Hex(password + SALT);
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getAccount, account)
                .eq(User::getPassword, s));
        if (user == null) {
            return Result.fail(ErrorCode.ACCOUNT_OR_PASSWORD_NOT_EXIST.getCode(), ErrorCode.ACCOUNT_OR_PASSWORD_NOT_EXIST.getMsg());
        }
        String token = JwtUtil.createToken(user.getId());
        redisTemplate.opsForValue().set("TOKEN_" + token, JSON.toJSONString(user), 30, TimeUnit.MINUTES);
        return Result.success("登录成功", token);
    }

    /**
     * 获取当前用户信息
     *
     * @param token 登录令牌
     * @return result
     */
    @Override
    public Result currentUser(String token) {
        if (token == null) {
            return Result.fail(ErrorCode.NO_LOGIN.getCode(), ErrorCode.NO_LOGIN.getMsg());
        }
        String s = JwtUtil.getClaimByToken(token).getSubject();
        if (s == null) {
            return Result.fail(ErrorCode.NO_LOGIN.getCode(), ErrorCode.NO_LOGIN.getMsg());
        }
        String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
        if (userJson == null) {
            return Result.fail(ErrorCode.NO_LOGIN.getCode(), ErrorCode.NO_LOGIN.getMsg());
        }
        User user = JSON.parseObject(userJson, User.class);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        return Result.success(userVo);
    }

    /**
     * 检测是否登录
     * @param token token
     * @return bool
     */
    @Override
    public Boolean checkLogin(String token) {
        if (token == null) {
            return false;
        }
        String s = JwtUtil.getClaimByToken(token).getSubject();
        if (s == null) {
            return false;
        }
        String userJson = redisTemplate.opsForValue().get("TOKEN_" + token);
        if (userJson == null) {
            return false;
        }
        return true;
    }

    /**
     * 注册
     * @param registerParam 注册参数
     * @return result
     */
    @Override
    public Result register(RegisterParam registerParam) {
        String account = registerParam.getAccount();
        String password = registerParam.getPassword();
        if (account == null || password == null) {
            return Result.fail(ErrorCode.REGISTER_ERROR.getCode(), ErrorCode.REGISTER_ERROR.getMsg());
        }
        User one = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getAccount, account));
        if (one != null) {
            return Result.fail(ErrorCode.REPEAT_REGISTER.getCode(), ErrorCode.REPEAT_REGISTER.getMsg());
        }
        one = new User();
        one.setAccount(account);
        one.setName(registerParam.getName());
        one.setArea(registerParam.getArea());
        one.setGender(registerParam.getGender());
        one.setLabel("成年");
        one.setIdCard(registerParam.getIdCard());
        one.setPoliticsStatus(registerParam.getPoliticsStatus());
        one.setBirthDate(registerParam.getBirthDate());
        one.setPassword(DigestUtils.md5Hex(password + SALT));
        userMapper.insert(one);
        return Result.success("注册成功");
    }

    /**
     * 登出
     * @param token token
     * @return result
     */
    @Override
    public Result logout(String token) {
        redisTemplate.delete("Token_" + token);
        return Result.success("登出成功");
    }

    /**
     * 更新user信息
     * @param setUserParam 用户信息更新参数
     * @return 结果
     */
    @Override
    public Result updateUser(SetUserParam setUserParam) {
        User user = new User();
        BeanUtils.copyProperties(setUserParam, user);
        String password = user.getPassword();
        user.setPassword(DigestUtils.md5Hex(password + SALT));
        int update = userMapper.update(user, new UpdateWrapper<User>()
                .eq("account", user.getAccount()));
        if (update == 1) {
            return Result.success("身份信息修改成功");
        } else return Result.fail("身份信息修改失败");
    }

    /**
     * 白名单检测
     * @param id 用户id
     * @return bool
     */
    @Override
    public Boolean whitelistDetection(Long id) {
        /*
        这里可以根据用户的id去黑名单数据库中进行匹配，如果
        有该用户就返回false，否则就返回true
        这里使用随机数进行模拟
         */
        int random = (int)(Math.random()*100);
        return random % 2 != 0;
    }
}
